home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / What's New? / Development Kits / Multiprocessing SDK / MP API FAQs < prev    next >
Encoding:
Text File  |  1998-09-25  |  19.7 KB  |  168 lines  |  [ttro/ttxt]

  1.  
  2.                     MP API - Frequently Asked Questions
  3.  
  4.                                                                                                                                                                                                                                     March 12, 1998
  5.  
  6.  
  7. * Questions marked with an asterix have been updated or added since Multiprocessing SDK #2
  8.  
  9. What is multiprocessing and multitasking?
  10. Multiprocessing is the use of more than one processor (CPU) simultaneously. By definition only a machine with more than one CPU is capable of multiprocessing. Multitasking allows multiple streams of execution to be created even if there is only a single CPU. The MP API implements a multiprocessing, multitasking environment. Any number of streams of execution can be created and one stream per CPU can be executing at any particular instant in time. Each stream of execution is called a task. Having concurrent tasks working on parts of some job, e.g. a ray trace, an image filter, a fractal etc., can reduce the overall time it takes to complete the job.
  11.  
  12. What is the MP API?
  13. The MP API allows a programmer to create tasks and to establish communication between them and the main application. A small number of other services are also available. The MP API document describes these services in detail.
  14.  
  15. What is the Multiprocessing API Library?
  16. The Multiprocessing API Library is a shared library that provides the services defined in the MP API. The Multiprocessing API Library also manages task scheduling and other task related issues. The library and its associated files are usually installed in the extensions folder. Storing the library in a subfolder within the extensions folder is recommended since this can reduce the amount of time required to launch MP-aware applications.
  17.  
  18. * What happened to MP.h?
  19. It went away. It has been replaced by "Multiprocessing.h". The stub file MP.h is provided in Universal Interfaces 3.0.1 but all it does is include "Multiprocessing.h" and it will eventually be phased out. Some of the constants that were in MP.h do not exist anymore, but their equivalents are pretty obvious. If in doubt use 0 or NULL, to get the defult behavior.
  20.  
  21. * What is a good way to install the library for development purposes?
  22. This topic is addressed in three parts, compiler access, application access, and debugging.
  23.  
  24. 1) Compiler access to the Multiprocessing API Library and the file Multiprocessing.h
  25. If you are running CodeWarrior Pro 2 or later, or any environment that provides the Universal Interfaces 3.0.1 or later, there is nothing you need to do. The library and header file are automatically available to the compiler.
  26.  
  27. In any other environment you should drag the "Multiprocessing" folder from the SDK into the compiler search path., e.g. the "MacOS Support:Headers:System Extras Headers:" folder for global access or your project folder for local access.
  28.  
  29. 2) Application access to the Multiprocessing API Library
  30. If you are using a multiprocessing machine, or you are running Mac OS 8 or later, there is nothing you need to do. The Multiprocessing API Library, the library will already be in a sub-folder in the extensions folder, and any application that attempts to weak-link to it will find it (Don't forget that the application should always weak-link to the Multiprocessing API Library, so that it can run even if the library is not present).
  31.  
  32. If you are using a uni-processor machine, or are running System 7, you will need to either copy the Multiprocessing API Library into the extensions folder, or make an alias to it in your extensions folder. The former is preferable since that is how most user machines will be set up and subtle Code Fragment Manager/Alias Manager problems can be avoided this way. If you do want to use an alias be sure that the actual Multiprocessing API Library resides somewhere on the startup disk or you will almost certainly run into problems.
  33.  
  34. 3) Debugger Support
  35. To single step through MP Tasks using the Metrowerks Debugger certain steps will have to be taken. Debugging is not enabled by default by any Metrowerks installers so all Metrowerks users will have to do one of the following:
  36.  
  37. CodeWarrior 9 to CodeWarrior Pro 1:
  38. Open MetroNub in the system Extensions folder using ResEdit and find the 'sysz' resource. Open this resource and change it to read 2500000. Close the file and reboot. Machines with large amounts of RAM may need to use an even higher number. 2500000 is sufficient for about 500MB of RAM or less. Increase the number in the 'sysz' resource linearly for machines with more than 500MB of RAM.
  39.  
  40. CodeWarrior Pro 2:
  41. Search the Mac OS Tools CD for "MetroNub for MP". Replace the "MetroNub" file in the system Extensions folder with the "MetroNub for MP" file. Use the French or English version as appropriate (only the French one is labelled as being such -the English one is in a folder named "for Extensions folder". Don't forget to delete the old MetroNub. Reboot the machine.
  42.  
  43. Code Warrior Pro 3:
  44. The steps involved should be very similar to CodeWarrior Pro 2.
  45.  
  46. * Why am I getting an "out of memory" warning after the Finder starts?
  47. If you get a warning that "The Multiprocessing Library could not be initialized due to a lack of memory" after the Finder starts then you will need to modify the Code Warrior extension MetroNub. Open MetroNub using ResEdit and find the 'sysz' resource. Open this resource and change it to read 2500000. Close the file and reboot. Machines containing more than 500MB of memory will need a proportionately larger number stored in the 'sysz' resource. Note that this only applies to CodeWarrior Pro 1 or less. See the entry "What is a good way to install the library for development purposes?" for more information.
  48.  
  49. What can tasks do?
  50.  In general tasks can execute any function accessable by your application. Tasks created using the MP API have the ability to access main memory and to communicate with other tasks as well as the application. Tasks must adhere to the restrictions outlined below.
  51.  
  52. What are the restrictions on tasks and the application?
  53. Tasks must not execute 68k code.
  54. Tasks must not call the Macintosh Toolbox.
  55. The application must not make MP API calls at interrupt time or from within a deferred task. However, there are safe techniques available for communicating with tasks at these times. Note that deferred tasks are defined in the Deferred Task Manager, they are not an MP API related concept.
  56.  
  57. How are tasks run?
  58. Tasks are inserted into a scheduling queue and are assigned to available processors. Tasks run preemptively. They run for a certain amount of time after which they will be interrupted and returned to the end of the scheduling queue. This way all tasks in the system can be assured fair access to the available processors. Tasks can also voluntarily return themselves to the scheduling queue using the MPYield() call. When a task blocks on one of the communication primitives, and that primitive is not available, the task is immediately suspended and the next task on the scheduling queue is run. Suspended tasks are not returned to the scheduling queue until the primitive on which they are waiting becomes available. Suspended tasks incur no system overhead.
  59.  
  60. How many tasks should I create?
  61. The number of tasks an application can create is not logically limited. Most applications will want to limit the creation of tasks that perform a given function to the number of available processors. As long as there are at least as many tasks performing work as there are available processors, maximum advantage of the system will be taken. Some problems are best decomposed into a fixed number of tasks, regardless of the number of processors. It is sometimes useful to have the main application perform some of the work also. This is especially true in applications that do not require the Multiprocessing API Library to be present. In this case the optimum number of tasks to create is one less than the number of processors. 
  62.  
  63. Do I need a multiprocessing system to use the MP API?
  64. No. If the Multiprocessing API Library is available so are all of its services. This means that you can create preemptive tasks on a PowerPC platform, provided those tasks adhere to the restrictions described above.
  65.  
  66. * What special tools do I need for development?
  67. You continue to use the same development tools you have always used. There are no special compilers or linkers to be used. All you add is a header file, Multiprocessor.h, as well as the Multiprocessing API Library.
  68.  
  69. * How do I weak link to the Multiprocessing API Library using CodeWarrior Pro?
  70. Select the Multiprocessing API Library in the project window and open the Project Inspector dialog from the Window menu. Check the Import Weak check box in the dialog.
  71.  
  72. * How do I debug this stuff?
  73. Metrowerks has provided MP debugging support with CodeWarrior 9 and later. Anything that can be done in the current Metrowerks debugging environment within applications should also be possible within tasks. Be sure to consult the entry "What is a good way to install the library for development purposes?" for instructions on how to enable Metrowerks Debugger support correctly.
  74.  
  75. * Why do tasks sometimes appear to stall directly after creation and never run, especially when debugging?
  76. This is an unfortunate side-effect of debugging protocols and can happen whether actively debugging or not.. Due to some subtle interactions with the Metrowerks Debugger, and with MacsBug, MP Tasks will stall immediately after creation waiting for the Debugger in charge to acknowledge and release them to a running state. If the application never calls SystemTask() directly or indirectly before requiring the tasks to run and create results, the Debugger in charge will never get an opportunity to release the tasks, and the application will stall waiting for results that will never come. Note that plug-in developers are particularly susceptible to this problem, since they occasionally create tasks and immediately wait for results without ever doing any event processing. The correct and complete solution to this problem is to structure the task creation loop in the following fashion:
  77.  
  78. for( i = 0; i < numTasks; i++ ) {
  79. ...
  80.     MPCreateTask( ... );
  81.     MPYield();                                                                                // Always call MPYield() after each MPCreateTask()
  82. ...
  83.     }
  84. MPYield();                                                                                    //    Always call MPYield() one more time after the loop is complete
  85.  
  86. The MPYield()'s are the important part. They make absolutely sure that all the Debuggers in the system have acknowledged and released the tasks. If you are not sure whether you need the MPYield()'s or not, put them in -they cost virtually nothing. Note SystemTask() indirectly calls MPYield() which is why things work okay when events are being actively processed.
  87.  
  88. * Are there any supported functions not described by the MP API documention?
  89. Yes -funny you should ask.
  90.  
  91. Boolean MPTaskIsToolboxSafe( MPTaskID task );
  92.  
  93. this was previously documented as an undocumented and hence unsupported function. Its status has changed and it is now supported. If this function returns true it is ok to make Toolbox calls. This is particularly useful if the application and MP Tasks share common code and you would like to spin a watch cursor, or update a progress dialog somewhere in that code. Don't forget to set your progress dialog to 100% after all the processing is done! Of course you could do anything else the Toolbox permits also.
  94.  
  95. void *MPRPC( MPRemoteProcedure theProc, void *parameter );
  96.  
  97. this function was not previously documented. It is now documented and supported. MPRPC() suspends the task and calls the MPRemoteProcedure parameter in the application's main thread the next time the application calls WaitNextEvent(), EventAvail(), SystemTask(), MPYield(), MPWaitOnQueue(), MPWaitOnSemaphore(), or MPEnterCriticalRegion(). The return value of the MPRemoteProcedure is returned as the result of MPRPC to the task, and the task is resumed. The MPRemoteProcedure function can call any toolbox function except WaitNextEvent(), EventAvail(), or SystemTask() (or anything that calls them). This function is very useful if your task absolutely must call the Toolbox for some reason. However, bear in mind that the cost of executing an MPRPC() call is relatively high and it should not be done frequently.
  98.  
  99. * Are there any undocumented functions that can help me with debugging?
  100. Yes, however these routines are not part of the Apple Multiprocessing API specification and they are not guaranteed to be supported in future versions of the Mac OS. Any function starting with an underscore should be considered to be undocumented and unsupported.
  101.  
  102. LogicalAddress _MPAllocateSys( ByteCount size );
  103.  
  104. Does the same thing as MPAllocate() except the memory is allocated from the system heap.
  105.  
  106. void _MPLibraryVersion( const char **versionCString,
  107.                                  UInt32 *major, UInt32 *minor, UInt32 *release, UInt32 *revision );
  108.  
  109. Retrieves the hardcoded version information built into the currently active Multiprocessing API Library.
  110.  
  111. void _MPDebugStr( ConstStr255Param msg );
  112.  
  113. This function works just like DebugStr() except that it is safe to call it from an MP task.
  114.  
  115. StringPtr _MPStatusPString( OSStatus status );
  116. StringPtr _MPStatusCString( OSStatus status );
  117.  
  118. These functions provide a way to translate an OSStatus value returned from one of the MP API calls into either a Pascal string or a C string. Thus, if an MPLibrary function returns an error then the application (not a task) could use the following:
  119.     status = MPxxx( function_params );
  120.     DebugStr( _MPStatusPString( status ) );
  121.  
  122. How can I test MP-savvy applications?
  123. Apple and DayStar recommend testing the MP-savvy applications on two platforms: a uniprocessor Macintosh and a multiprocessor Macintosh. The application code can be identical in both cases, but the application may have dependencies or race conditions that are only visible on a multiprocessor system.
  124.  
  125. When can I get started?
  126. You can start now. The Multiprocessing API Library included on this disk is the final product. It will allow you to create and test applications on uniprocessor systems that will run without modification on real multiprocessing systems (assuming no programming errors of course).
  127.  
  128. * Is hardware available?
  129. Hardware has been available from multiple sources since 1996. Umax is still actively selling systems at the time of writing, and Apple, DayStar, Power, Newer and other companies have all sold MP hardware in the past. The units have been sold mostly to high end customers in the publishing and digital video industry.
  130.  
  131. How will supporting the MP API impact my source base? What about 68K?
  132. The MP API cannot be used on 68k machines. You can have a single source base but the 68k side will not be able to create multiprocessing tasks -it should behave as though the Multiprocessing API Library is not present. The PPC side should also be able to handle the situation where the Multiprocessing API Library is not present. The same code can thus be used for both situations.
  133. If an application requires PPC and is also willing to require the presence of the Multiprocessing API Library, then tasks can be created and executed regardless of the number of processors in the system. Tasks created by an application are distributed preemptively amongst the available processors, even if there is only one, so task-creating code will work on any type of PPC system -multiprocessing or not.
  134.  
  135. * What will happen to the MP API when future versions of the Mac OS ships?
  136. The MP API will run on all current and planned versions of the PowerPC-based Mac OS. It will be installed by default in all versions from Mac OS 8 onward. Multiprocessing will be fully supported in the BlueBox under Rhapsody -if multiple processors are present they will be used. Note that the Multiprocessing API will not be the MP model under Rhapsody. However, the transition from the Mac OS MP API to the Rhapsody MP model should be relatively painless. There should be logical equivalents under Rhapsody for all the MP API calls.
  137.  
  138. How are the MP API and the Thread Manager related?
  139. The MP API and the Thread Manager can coexist within a single application, however their constructs and interfaces are not compatible. The principal difficulty with trying to make them compatible is that MP Tasks are fully preemptive, and may not call the Toolbox, whereas Threads are cooperative (under PowerPC) and may call the Toolbox. Unfortunately these are mutually exclusive properties given the current state of the Toolbox. Comfort can be taken from the fact that many developers have successfully combined Threads and MP Tasks in their applications with only minimal effort. It should be noted that a fully preemptive environment can be considerably more challenging to write for than a cooperative one. Using the MP API is excellent training for the day that we finally see SMP systems.
  140.  
  141. What are the basic steps I should take to implement multiprocessing?
  142. This question is handled in detail in the document "Multiprocessing Technote" on this SDK.
  143.  
  144. How should my application exploit multiprocessing?
  145. This question is handled in detail in the document "MacTech Article" included on this SDK.
  146.  
  147. Where can I find examples?
  148. Example code is provided in the "Sample Code" folder on this SDK.
  149.  
  150. How can I communicate with a task at interrupt time or from within a deferred task?
  151. Communication can be achieved by writing to a pre-agreed trigger location. A task can repeatedly poll this trigger until it changes. It is advisable to immediately precede all writes to the trigger with a call to __eieio(), especially if earlier changes to memory that the polling task requires have been made. This ensures that the earlier changes are really made before the trigger is set -PowerPCs do not necessarily write data to memory in the order requested. The task can call MPYield() while looping on the trigger which will ensure that it relinquishes the CPU while the trigger is not available. 
  152.  
  153. When the task is done it can issue an __eieio() and write to a trigger that the application is waiting on. If the application loops on the trigger be sure to remember NOT to call MPYield(). The Multiprocessing API Library is not interrupt safe and any attempt to call it at interrupt time or deferred task time will potentially cause a crash.
  154.  
  155. Never use this technique if you are writing a normal application.
  156.  
  157. What kind of problems can I expect from tasks sharing memory?
  158. Tasks should be careful about what memory they modify -it is not polite to modify memory being used by another task without communicating that fact to the other task. Modifying globals from within a task, or buffers pointed to by global variables should be avoided.
  159.  
  160. I crash after calling MPTerminateTask(). Why?
  161. MPTerminateTask() does not terminate a running task immediately. The task continues to run until it is preempted at which time it is terminated. Normal application cleanup techniques involve terminating the tasks and then disposing of all the semaphores, queues, memory, etc that the tasks were using. Unfortunately since the task doesn't really stop running straight away it starts using invalid data as the application starts deleting the shared resources. This can lead to catastrophic crashes. The best way to avoid this situation is to provide a termination queue when you create a task, and wait on the queue immediately after terminating the task. Once something is received you can be sure that the task is no longer running. Alternatively your application can notify a task that it is about to be terminated and wait for the task to acknowledge the notification. The task should not use any more shared resources after it sends the acknowledgement.
  162.  
  163. * How do I get support for the MP API?
  164. DayStar Digital is continuing to provide developer services for the MP API. You can contact MP developer support at mp@daystar.com. This address is still active and free support will still be given. Apple computer is also providing support for the MP API. You can contact Apple at devsupport@apple.com. You can also try mp@echofx.com. Many of the questions end up there anyway so you can cut out the middle man by mailing directly to that address if you wish.
  165.  
  166.  
  167. Copyright © Apple Computer, Inc. and DayStar Digital, Inc. 1995 - 1998
  168.